package me.zhengjie.modules.devicemap.service.query;

import me.zhengjie.utils.PageUtil;
import me.zhengjie.modules.devicemap.domain.DeviceMap;
import me.zhengjie.modules.devicemap.service.dto.DeviceMapDTO;
import me.zhengjie.modules.devicemap.repository.DeviceMapRepository;
import me.zhengjie.modules.devicemap.service.mapper.DeviceMapMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
* @author 张鹏
* @date 2019-06-03
*/
@Service
@CacheConfig(cacheNames = "deviceMap")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DeviceMapQueryService {

    @Autowired
    private DeviceMapRepository deviceMapRepository;

    @Autowired
    private DeviceMapMapper deviceMapMapper;

    /**
     * 分页
     */
    @Cacheable(keyGenerator = "keyGenerator")
    public Object queryAll(DeviceMapDTO deviceMap, Pageable pageable){
        Page<DeviceMap> page = deviceMapRepository.findAll(new Spec(deviceMap),pageable);
        return PageUtil.toPage(page.map(deviceMapMapper::toDto));
    }

    /**
    * 不分页
    */
    @Cacheable(keyGenerator = "keyGenerator")
    public Object queryAll(DeviceMapDTO deviceMap){
        return deviceMapMapper.toDto(deviceMapRepository.findAll(new Spec(deviceMap)));
    }

    class Spec implements Specification<DeviceMap> {

        private DeviceMapDTO deviceMap;

        public Spec(DeviceMapDTO deviceMap){
            this.deviceMap = deviceMap;
        }

        @Override
        public Predicate toPredicate(Root<DeviceMap> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {

            List<Predicate> list = new ArrayList<Predicate>();

                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(p));
        }
    }
}